import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:base_flutter/base_flutter.dart';
import 'package:base_flutter/src/utils/ext_utils.dart';
import 'package:dart_sm/dart_sm.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flustars_flutter3/flustars_flutter3.dart';
import 'package:flutter/foundation.dart';
import 'package:ls_work/common/common.dart';
import 'package:ls_work/message/message_config.dart';
import 'package:ls_work/net/net.dart';
import 'package:crypto/crypto.dart';

import '../login/page/login_page.dart';
import '../login/page/user_manager.dart';

class HttpUtil {
  factory HttpUtil() => _getInstance();

  /// instance的getter方法，通过UserManager.instance获取对象
  static HttpUtil get instance => _getInstance();

  /// 静态变量_instance，存储唯一对象
  static HttpUtil? _instance;

  /// 获取对象
  static HttpUtil _getInstance() {
    if (_instance == null) {
      // 使用私有的构造方法来创建对象
      _instance = new HttpUtil.internal();
    }
    return _instance!;
  }

  ///销毁单例
  HttpUtil get dealloc => attemptDealloc();

  // static Dio _dio;

  Dio getDio() {
    return HttpGo.instance.dio ??= Dio();
  }

  attemptDealloc() {
    _instance = null;
  }

  HttpUtil.internal({String? baseUrl}) {
    var options = BaseOptions(
      connectTimeout: Duration(milliseconds: 90000),
      receiveTimeout: Duration(milliseconds: 90000),
      responseType: ResponseType.plain,
      contentType: Headers.jsonContentType,
      headers: {
        'client-type': '3',
        'platform': Platform.isAndroid ? 'android' : 'iOS',
        'client-version': '${SpUtil.getString(Constant.locaVersion)}',
        'Accept-Language': 'zh',
        'user-agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36'
      },
      baseUrl: baseUrl ?? HttpApi.baseUrl,
    );
    HttpGo.instance.setOptions(options);
    HttpGo.instance.addInterceptor(MyCookieManager());

    /// Fiddler抓包代理配置 https://www.jianshu.com/p/d831b1f7c45b
    if (!Constant.inProduction) {
      // HttpGo.instance.setProxy("192.168.196.132", 8888, true);
      // HttpGo.instance.setProxy("192.168.110.90", 8888, false);
      // HttpGo.instance.setProxy("192.168.31.217", 8888, true);
    } else {
      DevConfig.instance.init();
    }
    (HttpGo.instance.dio?.httpClientAdapter as IOHttpClientAdapter)
        .createHttpClient = () {
      HttpClient client = HttpClient();
      if (BuildConfig.isDebug) {
        client.findProxy = (url) {
          return "PROXY 192.168.31.202:8888";
          // return "PROXY 192.168.110.66:8888";
        };
      } else {
        client.findProxy = null;
      }
      // client.findProxy =null;
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) {
        // print("sha====>${cert.issuer}==>${host}==?${getDerSha256Thumbprint(cert)}");
        return _verifyCertificate(cert, host);
      };

      return client;
    };
  }

  String getCertificateSha256Thumbprint(X509Certificate cert) {
    // 移除PEM格式的头部和尾部
    final pem = cert.pem
        .replaceAll('-----BEGIN CERTIFICATE-----', '')
        .replaceAll('-----END CERTIFICATE-----', '')
        .replaceAll('\n', '');

    // Base64解码
    final bytes = base64.decode(pem);

    // 计算SHA256
    final digest = sha256.convert(bytes);

    // 返回十六进制字符串
    return digest.toString();
  }

  static String getDerSha256Thumbprint(X509Certificate cert) {
    final der = cert.der.reversed.toList();
    final digest = sha256.convert(der);
    return digest.toString();
  }

  static bool _verifyCertificate(X509Certificate cert, String host) {
    // 实现你的证书验证逻辑
    const allowedFingerprints = [
      'd4f4df0460f229b87634029d8b5ff4e48653a44a29f53a066bde28c73c9a8548'
    ];

    var sha256 = getDerSha256Thumbprint(cert);
    return allowedFingerprints.contains(sha256);
  }

  static String formatError(e) {
    if (e is DioException) {
      if (e.type == DioExceptionType.connectionTimeout) {
// It occurs when url is opened timeout.

        return "连接超时";
      } else if (e.type == DioExceptionType.sendTimeout) {
// It occurs when url is sent timeout.

        return "请求超时";
      } else if (e.type == DioExceptionType.receiveTimeout) {
//It occurs when receiving timeout

        return "响应超时";
      } else if (e.type == DioExceptionType.badResponse) {
// When the server response, but with a incorrect status, such as 404, 503...
        return checkError2(e);
      } else if (e.type == DioExceptionType.cancel) {
// When the request is cancelled, dio will throw a error with this type.
        return "";
      } else if (e.type == DioExceptionType.unknown) {
        return e.message ?? "";
      } else {
//DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
        return "未知错误";
      }
    } else {
      return e.toString();
    }
  }

  Future<Map> postData(
    url, {
    data,
    options,
    cancelToken,
  }) async {
    var response = await HttpGo.instance.dio
        ?.post(url, data: data, options: options, cancelToken: cancelToken);
    if (response?.data is String) {
      return Future.value(response?.data.toString().toMap());
    } else {
      return Future.value(response?.data);
    }
  }

  Future<Map> getData(
    url, {
    data,
    options,
    cancelToken,
  }) async {
    Response? response = await HttpGo.instance.dio?.get(url,
        queryParameters: data, options: options, cancelToken: cancelToken);
    if (response?.data is String) {
      return Future.value(response?.data.toString().toMap());
    } else {
      return Future.value(response?.data);
    }
  }

  static String checkError(String message) {
    if (message.contains("404")) {
      return "【404】调用方法未找到";
    } else if (message.contains("500")) {
      return "【500】服务器发生异常";
    } else if (message.contains("503")) {
      return "【503】服务器发生异常";
    } else if (message.contains("403")) {
      return "【403】无访问权限，请联系管理员开通权限";
    } else {
      return message;
    }
  }

  static String checkError2(DioException error) {
    if (error.response?.statusCode == 404) {
      return "【404】调用方法未找到";
    } else if (error.response?.statusCode == 500) {
      return "【500】服务器发生异常";
    } else if (error.response?.statusCode == 503) {
      return "【503】服务器发生异常";
    } else if (error.response?.statusCode == 403) {
      return "【403】无访问权限，请联系管理员开通权限";
    } else {
      return "【${error.response?.statusCode}】服务器发生错误";
    }
  }
}

String requestParams(dynamic value) {
  return "jsonStr=${json.encode(value)}";
}

String getErrorMessage(dynamic error) {
  // switch (type) {
  //   case DioExceptionType.unknown:
  //     return "网络不可用，请检查网络";
  //   case DioExceptionType.connectionTimeout:
  //     return "网络连接超时,请重试";
  //   case DioExceptionType.sendTimeout:
  //     return "数据发送超时,请重试";
  //   case DioExceptionType.receiveTimeout:
  //     return "数据接受超时,请重试";
  //   case DioExceptionType.badResponse:
  //     return "无法连接服务器，请重试";
  //   case DioExceptionType.cancel:
  //     return "网络连接已取消";
  //   default:
  //     return "";
  // }
  return HttpUtil.formatError(error);
}

class MyCookieManager extends InterceptorsWrapper {
  bool hasError = false;

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {

    if(response.requestOptions.path.contains("checkCode/getCheckCode")){
      // print("12123321");
      super.onResponse(response, handler);
      return;
    }

    var cookie = initCookies(response);
    if (cookie.isNotEmpty) {
      var map = {"cookie": cookie};
      UserManager.instance.saveCookie(map);
    }
    var responseStr = response.data.toString();
    // print("responseStr====>${responseStr}");
    if (!responseStr.contains("{")) {
      var publicKey = UserManager.itemKey;
      if (publicKey.isNullOrEmpty()) {
        publicKey =
            "318b42567f1639f605e90e6e198bb179f960f9a118fa7fb972aee9850cfe115e";
      }
      try {
        var json = SM2.decrypt(responseStr, publicKey);
        if (BuildConfig.isDebug) {
          // log("${response.realUri.toString()}\n${json}");
        }
        response.data = json;
      } catch (e) {
        // print(e);
      }
      super.onResponse(response, handler);
    } else {
      super.onResponse(response, handler);
    }
  }

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    var cookie = UserManager.cookieStr;
    if (cookie.isNotEmpty) {
      options.headers["cookie"] = cookie;
    } else {
      options.headers.remove("cookie");
    }

    super.onRequest(options, handler);
  }

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    if ((err.response?.statusCode ?? 0) == 401) {
      if (!hasError) {
        // if (UserManager.pdd.isNullOrEmpty()) {
        Go().pushRemoveUntil(LoginPage(
          error: UserManager.cookieStr.isNullOrEmpty()
              ? "登录信息失效，请重新登录"
              : "登录失效，请重新登录",
        ));
        UserManager.instance.logout();
        hasError = true;
        Future.delayed(
            Duration(
              seconds: 3,
            ), () {
          hasError = false;
        });
        // } else {
        //   eventBus.fire(SendMessageEvent(MessageConfig.RELOGIN));
        // }
      }
    } else {
      super.onError(err, handler);
    }
  }
}

String initCookies(Response response) {
  var cookies = response.headers[HttpHeaders.setCookieHeader];

  var itemStr = UserManager.cookieStr;
  List<String> items = itemStr.isNullOrEmpty() ? [] : itemStr.split(";");
  if (cookies != null && cookies.isNotEmpty) {
    for (var cookie in cookies) {
      var data = cookie.split(";")[0];
      var list = data.split("=");
      if (list[0] != "rememberMe" && list[1].contains("-")) {
        items.add(data);
      }
    }

    var map = <String, dynamic>{};
    for (var str in items) {
      var key = str.split("=")[0];
      var value = str.split("=")[1];
      map[key] = value;
    }
    var list = map.keys.map((e) => "$e=${map[e]}").toList();
    return list.join(";");
  } else {
    return "";
  }
}
